#!/usr/bin/env python2
# ----------------------------------------------------------------------------
# Scan QUEUE_IN for completed messages and feed to inews and remove the file.
# Remove too-old QUEUE_IN content. Automatically remove files from blacklisted
# ids. Check if any complete messages don't match their msgid - would it ever
# be a problem? HDLC/AX.25 has reasonable packet CRCs...

import os, zlib, sys, time
import site_config as cfg
import qrpbbb_lib as lib

#

print "\nqrpbbb_queuecheck.py executing at:", time.ctime()

MAXAGE = cfg.QUEUE_TOOOLD

while len(sys.argv) > 1:
    if sys.argv[1].isdigit():
        MAXAGE = int (sys.argv[1])
        print "Holding incomplete messages for", MAXAGE, "days.\n"
    sys.argv = sys.argv[1:]

#
#
#

def fileaction (f, reason):
    print "Has an issue: %s" % reason
    print "r=remove, f=from-scratch CR=skip (editing and uhave are also options)"
    l = raw_input()
    if "r" in l:
        print "Removing", f
        os.remove (f)

    if "f" in l:
        name = os.path.basename (f)
        message = lib.fetch_message (f)
        for i in range (1, len(message)+1):
            message[i] = -1
        print "Overwriting", f
        lib.update_message (name, message)

#
# Searches through all of message[]
#

def checkheaders(regexp,message):
    # Sorry. But this really is the only obfuscated Pythonic trick I use..
    return filter (lambda v: re.match(regexp,v), message)[0].rstrip()

#
#
#

(cntposted, cntfailpost, cntincomp, cntcorrupt) = (0,0,0,0)

for f in lib.queuein_filelist():
    name = os.path.basename (f)
    message = lib.fetch_messagetext (f)
    contenthash = lib.message_hash (message)
    print f, " contenthash:", contenthash

    if lib.badmsg_check (contenthash):
        print "  this message is being ignored, removing"
        os.remove (f)
        continue

    # check age...
    t = (time.time() - os.path.getctime (f)) / 86400
    if t >= MAXAGE:
        fileaction (f, "Over " + str(MAXAGE) + " days old.")
        continue

    # completed and error-free - give to the newsserver
    if contenthash == name:
        s = cfg.INEWS + " -h -O -S " + f
        print "    Executing:", s
        r = os.system (s)
        if r:
            print "    oh, a problem"
            cntfailpost += 1
            # almost always a Dup from a message with a changed msgid
            # add to BadMsgid list
            #lib.badmsg_append (contenthash)
        else:
            try:
                messageid = checkheader ('^Message-ID:', message)
                newsgroup = checkheader ('^Newsgroups:', message)
                distro    = checkheader ('^Distribution:', message)
                fromname  = checkheader ('^From:', message)
                subject   = checkheader ('^Subject:', message)
                s = ' '.join((time.strftime ("%Y-%M-%d %H:%M:%S"),
                              f, messageid, newsgroup, distro, fromname, subject))
            except:
                s = time.ctime() + " a busted posting with missing headers"

            foo = open (cfg.POSTLOG, 'a')
            foo.write (s + "\n")
            foo.close()
            cntposted += 1

        print "    Removing", f
        os.remove (f)
        #lib.badmsg_append (contenthash)

    #
    else:
        # check if all the lines have supposedly been received
        message = lib.fetch_message (f)
        (cntmissing, incomplete) = (0, False)
        for i in range (1, len(message)+1):
            if message[i] == -1:
                cntmissing += 1
                incomplete = True
        if not incomplete:
            fileaction (f, "Mismatching hash, likely data corruption.")
            cntcorrupt += 1
        else:
            print "    Still being received.", cntmissing,"lines to go."
            cntincomp += 1

    print

if (cntposted):
    print "Completed and posted messages:", cntposted
if (cntfailpost):
    print "Completed but failed injections:", cntfailpost
if (cntincomp):
    print "Remaining incompete messages:", cntincomp
if (cntcorrupt):
    print "Corrupted messages:", cntcorrupt

#
# ----------------------------------------------------------------------------
#
